#ifndef __TIME_AND_RANDOM__
#define __TIME_AND_RANDOM__

#include <chrono>
#include <cstdlib> // for srand() rand()
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <tuple>
#include <vector>

/* 获取当前时间 */
inline auto Now() -> std::chrono::time_point<std::chrono::system_clock> { return std::chrono::system_clock::now(); }

/* 输入time_point，返回字符串，输出毫秒可选 */
inline auto TimeToString(std::chrono::time_point<std::chrono::system_clock> given_time, bool include_ms = true)
    -> std::string {
    auto timestring = std::ostringstream{};
    auto timet      = std::chrono::system_clock::to_time_t(given_time);
    timestring << std::put_time(std::localtime(&timet), "%Y-%m-%d %H:%M:%S");
    if (include_ms) {
        auto seconds   = std::chrono::duration_cast<std::chrono::seconds>(given_time.time_since_epoch());
        auto mlseconds = std::chrono::duration_cast<std::chrono::milliseconds>(given_time.time_since_epoch());
        timestring << "." << std::setfill('0') << std::setw(3) << (mlseconds - seconds).count();
    }
    return timestring.str();
}

inline auto TimeToInt(std::chrono::time_point<std::chrono::system_clock> given_time) -> std::tuple<int, int> {
    auto seconds =
        static_cast<int>(std::chrono::duration_cast<std::chrono::seconds>(given_time.time_since_epoch()).count());
    auto mlseconds =
        static_cast<int>(std::chrono::duration_cast<std::chrono::milliseconds>(given_time.time_since_epoch()).count());
    return std::make_tuple(seconds, mlseconds);
}

inline auto frand() -> double {
    srand(std::chrono::duration_cast<std::chrono::microseconds>(Now().time_since_epoch()).count());
    auto result = (rand() / double{RAND_MAX} - 0.5) * 2;
    return result;
}; // return random double between (-1, 1)

#endif // __TIME_AND_RANDOM__